/**
 * 
 */
package vue.globalBar;

import java.awt.Dimension;
import java.awt.GridLayout;
import java.util.LinkedList;
import java.util.List;

import javax.swing.BorderFactory;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

import vue.IIGSATPart;
import vue.session.IGBlock;
import vue.session.IGCNFUse;
import vue.session.IGExecutionBlock;
import vue.session.IGPreprocessorBlock;
import vue.session.IGSolverBlock;
import controller.ISessionManager;


/**
 * It is "bar" that the information relative to the solver/preprocessor being, or that have been
 * executed, in the session.
 * 
 * @author GRONOWSKI Stephane svan001@aol.com
 * 
 *         igsat 2010
 * 
 */
public class IGGlobalExecutionBar extends JPanel implements IIGSATPart {

	private static final long		serialVersionUID		= 1L;
	public static final String		BORDER_TITLE			= "Global Execution Bar";
	public static final String		BORDER_RUNNING			= "Currentely running";
	public static final String		BORDER_DONE				= "Previous execution";
	public static final String		BORDER_STATUS			= "Current status";


	public static final String		DEFAULT_STATUS_MESSAGE	= "Undetermined";
	public static final String		SAT_STATUS_MESSAGE		= "satisfiable !!";
	public static final String		UNSAT_STATUS_MESSAGE	= "Unsatisfiable !!";

	public static final int			HEIGHT					= 700;
	public static final int			WIDTH					= 300;

	protected int					width					= WIDTH;
	protected int					height					= HEIGHT;
	protected Dimension				dim;


	private JPanel					runningPanel;
	private JPanel					donePanel;

	private ISessionManager			manager;

	private List<IGBarSolver>		solverDone				= new LinkedList<IGBarSolver>();
	private List<IGBarPreprocessor>	preprocDone				= new LinkedList<IGBarPreprocessor>();
	private List<IGBarExecution>	running					= new LinkedList<IGBarExecution>();

	private IGBlock					selected				= null;


	public IGGlobalExecutionBar(ISessionManager manager) {
		// setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
		setLayout(new GridLayout(2, 1));
		dim = new Dimension(width, height);
		this.manager = manager;

		// setLayout(new GridBagLayout());

		/*
		 * statusLabel = new JLabel("", JLabel.CENTER);
		 * statusLabel.setAlignmentX(JLabel.CENTER_ALIGNMENT);
		 * statusLabel.setAlignmentY(JLabel.CENTER_ALIGNMENT); setUndeterminedStatus();
		 * statusLabel.setBorder(BorderFactory.createTitledBorder(BORDER_STATUS));
		 * statusLabel.setMaximumSize(new Dimension(width, height)); statusLabel.setOpaque(true);
		 * 
		 * add(statusLabel);
		 */
		JScrollPane scroll;

		runningPanel = new JPanel(new GridLayout(0, 1));
		scroll = new JScrollPane(runningPanel);
		scroll.setBorder(BorderFactory.createTitledBorder(BORDER_RUNNING));
		// scroll.setAlignmentX(JPanel.CENTER_ALIGNMENT);
		// scroll.setAlignmentY(JPanel.CENTER_ALIGNMENT);
		// scroll.setMaximumSize(dim);

		add(scroll);

		donePanel = new JPanel(new GridLayout(0, 1));
		// donePanel = new JPanel();
		// donePanel.setLayout(new BoxLayout(donePanel, BoxLayout.Y_AXIS));
		scroll = new JScrollPane(donePanel);
		scroll.setBorder(BorderFactory.createTitledBorder(BORDER_DONE));
		// scroll.setAlignmentX(JPanel.CENTER_ALIGNMENT);
		// scroll.setAlignmentY(JPanel.CENTER_ALIGNMENT);
		// scroll.setMaximumSize(dim);

		add(scroll);

		setBorder(BorderFactory.createTitledBorder(BORDER_TITLE));

		setPreferredSize(dim);
		setSize(dim);
	}

	@Override
	public void addCNFUse(IGCNFUse cnfuse) {
		// TODO Auto-generated method stub

	}

	@Override
	public void addExecution(IGCNFUse cnfuse, IGExecutionBlock exec) {
		IGBarExecution tmp = new IGBarExecution(exec, manager);
		running.add(tmp);
		runningPanel.add(tmp);
	}

	@Override
	public void addPreprocessor(IGCNFUse cnfuse, IGPreprocessorBlock preproc, IGCNFUse res) {
		IGBarPreprocessor tmp = new IGBarPreprocessor(preproc, manager);
		preprocDone.add(tmp);
		donePanel.add(tmp);
	}

	@Override
	public void addSolver(IGCNFUse cnfuse, IGSolverBlock solver) {
		System.out.println("ajoute solver");
		IGBarSolver tmp = new IGBarSolver(solver, manager);
		solverDone.add(tmp);
		donePanel.add(tmp);
	}

	@Override
	public void hasBeenModified(IGBlock block) {
		// TODO A tester
		for (IGBarExecution exec : running)
			if (exec.getExec() == block)
			{
				exec.refresh();
				return;
			}

		for (IGBarSolver exec : solverDone)
			if (exec.getSolver() == block)
			{
				exec.refresh();
				return;
			}

		for (IGBarPreprocessor exec : preprocDone)
			if (exec.getPreproc() == block)
			{
				exec.refresh();
				return;
			}
	}

	@Override
	public void hasBeenRemoved(IGBlock block) {
		// TODO A tester
		if (selected == block)
			selected = null;

		IGBarExecution ex = null;
		for (IGBarExecution exec : running)
			if (exec.getExec() == block)
			{
				ex = exec;
				break;
			}
		if (ex != null)
		{
			running.remove(ex);
			runningPanel.remove(ex);
			runningPanel.repaint();
			return;
		}

		IGBarSolver sol = null;
		for (IGBarSolver exec : solverDone)
			if (exec.getSolver() == block)
			{
				sol = exec;
				break;
			}
		if (sol != null)
		{
			solverDone.remove(sol);
			donePanel.remove(sol);
			donePanel.repaint();
			return;
		}

		IGBarPreprocessor pre = null;
		for (IGBarPreprocessor exec : preprocDone)
			if (exec.getPreproc() == block)
			{
				pre = exec;
				break;
			}
		if (pre != null)
		{
			preprocDone.remove(pre);
			donePanel.remove(pre);
			donePanel.repaint();
			return;
		}
	}

	@Override
	public void hasBeenSelected(IGBlock block) {
		// TODO Auto-generated method stub
		if (selected == block || block == null)
			return;

		IGBlock oldSelected = selected;
		selected = null;
		boolean select = false;
		boolean deselect;

		if (oldSelected == null)
			deselect = true;
		else
			deselect = false;

		for (IGBarExecution exec : running)
		{
			if (!deselect && exec.getExec() == oldSelected)
			{
				exec.setSelected(false);

				if (select)
					return; // deja deselectionner et selectionner le nouveau
				else
					deselect = true;
				continue;
			}

			if (!select && exec.getExec() == block)
			{
				exec.setSelected(true);
				selected = block;

				if (deselect)
					return; // deja deselectionner et selectionner le nouveau
				else
					select = true;
				continue;
			}
		}

		for (IGBarSolver exec : solverDone)
		{
			if (!deselect && exec.getSolver() == oldSelected)
			{
				exec.setSelected(false);

				if (select)
					return; // deja deselectionner et selectionner le nouveau
				else
					deselect = true;
				continue;
			}

			if (!select && exec.getSolver() == block)
			{
				exec.setSelected(true);
				selected = block;

				if (deselect)
					return; // deja deselectionner et selectionner le nouveau
				else
					select = true;
				continue;
			}
		}

		for (IGBarPreprocessor exec : preprocDone)
		{
			if (!deselect && exec.getPreproc() == oldSelected)
			{
				exec.setSelected(false);

				if (select)
					return; // deja deselectionner et selectionner le nouveau
				else
					deselect = true;
				continue;
			}

			if (!select && exec.getPreproc() == block)
			{
				exec.setSelected(true);
				selected = block;

				if (deselect)
					return; // deja deselectionner et selectionner le nouveau
				else
					select = true;
				continue;
			}
		}
	}

	/*
	 * @Override public void setSatisfiableStatus() { statusLabel.setText(SAT_STATUS_MESSAGE);
	 * statusLabel.setBackground(Color.GREEN); }
	 * 
	 * @Override public void setUnatisfiableStatus() { statusLabel.setText(UNSAT_STATUS_MESSAGE);
	 * statusLabel.setBackground(Color.RED); }
	 * 
	 * @Override public void setUndeterminedStatus() { statusLabel.setText(DEFAULT_STATUS_MESSAGE);
	 * statusLabel.setBackground(Color.GRAY); }
	 */


}
